﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using TomanuExtensions.Utils;

namespace AmiEmuLib.AmigaMachine.AmigaCPU
{
    /// <summary>
    /// Methods to work with status register.
    /// </summary>
    internal static class SR68000
    {
        public const int BIT_TRACE = 15;
        public const int BIT_SUPERVISOR = 13;

        public const ushort MASK_TRACE = 1 << BIT_TRACE;
        public const ushort MASK_SUPERVISOR = 1 << BIT_SUPERVISOR;
        public const ushort MASK_INTERRUPTS = 7 << 8;

        /// <summary>
        /// Get trace.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <returns></returns>
        public static bool IsTrace(ushort a_sr)
        {
            return Bits.IsSet(a_sr, BIT_TRACE);
        }

        /// <summary>
        /// Set trace.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <param name="a_bitValue"></param>
        public static void SetTrace(ref ushort a_sr, bool a_bitValue)
        {
            Bits.SetBit(ref a_sr, BIT_TRACE, a_bitValue);
        }

        /// <summary>
        /// Supervisor.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <returns></returns>
        public static bool IsSupervisor(ushort a_sr)
        {
            return Bits.IsSet(a_sr, BIT_SUPERVISOR);
        }

        /// <summary>
        /// Supervisor.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <param name="a_bitValue"></param>
        public static void SetSupervisor(ref ushort a_sr, bool a_bitValue)
        {
            Bits.SetBit(ref a_sr, BIT_SUPERVISOR, a_bitValue);
        }

        /// <summary>
        /// Interrupt mask.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <returns></returns>
        public static uint GetInterruptMask(ushort a_sr)
        {
            return (uint)(a_sr & MASK_INTERRUPTS) >> 8;
        }

        /// <summary>
        /// Interript mask.
        /// </summary>
        /// <param name="a_sr"></param>
        /// <param name="a_mask"></param>
        public static void SetInterruptMask(ref ushort a_sr, byte a_mask)
        {
            a_sr = (ushort)((a_sr & ~MASK_INTERRUPTS) | (a_mask << 8));
        }

        public static string Info(ushort a_sr)
        {
            return String.Format("{0}, TRACE:{1}, SUPERVISOR:{2}, INTMASK:{3}", 
                Hex.UShortToHex(a_sr), IsTrace(a_sr) ? "T" : "F", IsSupervisor(a_sr) ? "T" : "F", 
                GetInterruptMask(a_sr));
        }
    }
}
